Add xenversion support
authorjfisch@us.ibm.com <jfisch@us.ibm.com>
Tue, 23 Aug 2005 01:10:59 +0000 (02:10 +0100)
committerjfisch@us.ibm.com <jfisch@us.ibm.com>
Tue, 23 Aug 2005 01:10:59 +0000 (02:10 +0100)
tools/xenstat/libxenstat/src/xen-interface.c
tools/xenstat/libxenstat/src/xen-interface.h
tools/xenstat/libxenstat/src/xenstat.c
tools/xenstat/libxenstat/src/xenstat.h

index 9629237fc6f16df6d471d93845f689e4cfbba162..876560fd1ee4039852681d75649bab0bcb92c5d6 100644 (file)
@@ -21,7 +21,9 @@
 #include <sys/mman.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
+#include "version.h"
 #include "privcmd.h"
 #include "xen.h"
 
@@ -56,24 +58,69 @@ void xi_uninit(xi_handle *handle)
        free (handle);
 }
 
-/* Make Xen hypervisor call */
-int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode)
+/* Make simple xen version hypervisor calls */
+static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
+{
+       privcmd_hypercall_t privcmd;
+       multicall_entry_t multicall[2];
+       int ret = 0;
+
+       /* set up for doing hypercall */
+       privcmd.op = __HYPERVISOR_multicall; 
+       privcmd.arg[0] = (unsigned long)multicall;
+       privcmd.arg[1] = 2;
+
+       /* first one to get xen version number */
+       multicall[0].op = __HYPERVISOR_xen_version;
+       multicall[0].args[0] = (unsigned long)XENVER_version;
+
+       /* second to get xen version flag */
+       multicall[1].op = __HYPERVISOR_xen_version; 
+       multicall[1].args[0] = (unsigned long)XENVER_extraversion;
+       multicall[1].args[1] = (unsigned long)ver;
+
+       if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
+               perror("Failed to mlock privcmd structure");
+               return -1;
+       }
+
+       if (mlock( multicall, sizeof(multicall_entry_t)) < 0) {
+               perror("Failed to mlock multicall_entry structure");
+               munlock( &multicall, sizeof(multicall_entry_t));
+               return -1;
+       }
+
+       if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
+               perror("Hypercall failed");
+               ret = -1;
+       }
+
+       *vnum = multicall[0].result;
+
+       munlock( &privcmd, sizeof(privcmd_hypercall_t));
+       munlock( &multicall, sizeof(multicall_entry_t));
+
+       return ret;
+}
+
+/* Make Xen Dom0 op hypervisor call */
+static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op, int dom_opcode)
 {
        privcmd_hypercall_t privcmd;
        int ret = 0;
 
        /* set up for doing hypercall */
        privcmd.op = __HYPERVISOR_dom0_op;
-       privcmd.arg[0] = (unsigned long)op;
-       op->cmd = opcode;
-       op->interface_version = DOM0_INTERFACE_VERSION;
+       privcmd.arg[0] = (unsigned long)dom_op;
+       dom_op->cmd = dom_opcode;
+       dom_op->interface_version = DOM0_INTERFACE_VERSION;
 
        if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
                perror("Failed to mlock privcmd structure");
                return -1;
        }
 
-       if (mlock( op, sizeof(dom0_op_t)) < 0) {
+       if (mlock( dom_op, sizeof(dom0_op_t)) < 0) {
                perror("Failed to mlock dom0_op structure");
                munlock( &privcmd, sizeof(privcmd_hypercall_t));
                return -1;
@@ -85,7 +132,7 @@ int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode)
        }
 
        munlock( &privcmd, sizeof(privcmd_hypercall_t));
-       munlock( op, sizeof(dom0_op_t));
+       munlock( dom_op, sizeof(dom0_op_t));
 
        return ret;
 }
@@ -142,3 +189,16 @@ long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain,
 
        return op.u.getvcpucontext.cpu_time;
 }
+
+/* gets xen version information from hypervisor */
+int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver) 
+{
+
+        /* gets the XENVER_version and XENVER_extraversion */
+       if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {; 
+               perror("XEN VERSION Hypercall failed");
+               return -1;
+       }
+
+       return 0;
+}
index 45f882ce4912fda45b4fc2a26f5391bbd2d7f3ea..c60655a378bc2ead943ef3c0a38a709c091d7f20 100644 (file)
@@ -27,6 +27,7 @@ typedef uint32_t u32;
 typedef uint64_t u64;
 
 #include "dom0_ops.h"
+#include "version.h"
 
 /* Opaque handles */
 typedef struct xi_handle xi_handle;
@@ -38,6 +39,9 @@ xi_handle *xi_init();
 /* Release the handle to libxc, free resources, etc. */
 void xi_uninit(xi_handle *handle);
 
+/* Obtain xen version information from hypervisor */
+int xi_get_xen_version(xi_handle *, long *vnum, xen_extraversion_t *ver);
+
 /* Obtain physinfo data from dom0 */
 int xi_get_physinfo(xi_handle *, dom0_physinfo_t *);
 
index 85ffc0872d744e383169b986fd24b54391fdb579..52f3e6741b16bb5130d1777843c28f678c45df35 100644 (file)
@@ -22,6 +22,7 @@
 #include <unistd.h>
 #include <xen-interface.h>
 #include "xenstat.h"
+#include "version.h"
 
 /*
  * Types
@@ -32,6 +33,9 @@ struct xenstat_handle {
        FILE *procnetdev;
 };
 
+#define SHORT_ASC_LEN 5                /* length of 65535 */
+#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
+
 struct xenstat_node {
        unsigned int flags;
        unsigned long long cpu_hz;
@@ -39,6 +43,7 @@ struct xenstat_node {
        unsigned long long tot_mem;
        unsigned long long free_mem;
        unsigned int num_domains;
+       char xen_version[VERSION_SIZE]; /* xen version running on this node */
        xenstat_domain *domains;        /* Array of length num_domains */
 };
 
@@ -47,7 +52,7 @@ struct xenstat_domain {
        unsigned int state;
        unsigned long long cpu_ns;
        unsigned int num_vcpus;
-       xenstat_vcpu *vcpus;    /* Array of length num_vcpus */
+       xenstat_vcpu *vcpus;            /* Array of length num_vcpus */
        unsigned long long cur_mem;     /* Current memory reservation */
        unsigned long long max_mem;     /* Total memory allowed */
        unsigned int ssid;
@@ -164,6 +169,8 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags)
 #define DOMAIN_CHUNK_SIZE 256
        xenstat_node *node;
        dom0_physinfo_t physinfo;
+       xen_extraversion_t version;
+       long vnum = 0; 
        dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE];
        unsigned int num_domains, new_domains;
        unsigned int i;
@@ -179,6 +186,14 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags)
                return NULL;
        }
 
+       /* Get the xen version number and xen version tag */
+       if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) {
+               free(node); 
+               return NULL;
+       } 
+       snprintf(node->xen_version, VERSION_SIZE,
+               "%ld.%ld%s\n", ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, (char *)version); 
+
        node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL;
        node->num_cpus =
            (physinfo.threads_per_core * physinfo.cores_per_socket *
@@ -247,8 +262,8 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags)
                        if(collectors[i].collect(handle, node) == 0) {
                                xenstat_free_node(node);
                                return NULL;
-                        }
-                }
+                       }
+               }
        }
 
        return node;
@@ -291,6 +306,11 @@ xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node,
        return NULL;
 }
 
+const char *xenstat_node_xen_ver(xenstat_node * node)
+{
+       return node->xen_version;
+}
+
 unsigned long long xenstat_node_tot_mem(xenstat_node * node)
 {
        return node->tot_mem;
index 7542a07d983fa1ef03e73f43ab0c7eb1630dc593..2c3617e302158eee867dd4a87d4b4ea542857255 100644 (file)
@@ -51,6 +51,8 @@ xenstat_domain *xenstat_node_domain(xenstat_node * node,
 /* Get the domain with the given index; used to loop over all domains. */
 xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node,
                                             unsigned index);
+/* Get xen version of the node */
+const char *xenstat_node_xen_ver(xenstat_node * node);
 
 /* Get amount of total memory on a node */
 unsigned long long xenstat_node_tot_mem(xenstat_node * node);